import { Statistics } from "../../models/Statistics.mjs";
import { School } from "../../models/School.mjs";
import { Province } from "../../models/Province.mjs";

export class StatisticsService {
  // 更新统计数据
  static async updateStatistics(schools, provinces) {
    const statistics = await this.calculateStatistics(schools, provinces);
    return Statistics.findOneAndUpdate(
      { type: "school" },
      {
        data: statistics,
        lastUpdated: new Date(),
      },
      { upsert: true, new: true }
    );
  }

  // 获取专业层级数据
  static async getMajorHierarchy(level, code) {
    const statistics = await Statistics.findOne({ type: "school" });
    if (!statistics || !statistics.data.majorHierarchy) {
      throw new Error("未找到统计数据");
    }

    const hierarchy = statistics.data.majorHierarchy;
    let result;

    switch (level) {
      case "level1":
        result = this.getLevel1Hierarchy(hierarchy, code);
        break;
      case "level2":
        result = this.getLevel2Hierarchy(hierarchy, code);
        break;
      case "level3":
        result = this.getLevel3Hierarchy(hierarchy, code);
        break;
      default:
        throw new Error("无效的层级参数");
    }

    if (!result) {
      throw new Error("未找到指定代码的数据");
    }

    return result;
  }

  // 获取专业分布数据
  static async getMajorDistribution() {
    const statistics = await Statistics.findOne({ type: "school" });

    if (statistics && statistics.data.majorDistribution) {
      return {
        data: statistics.data.majorDistribution,
        lastUpdated: statistics.lastUpdated,
      };
    }

    const schools = await School.find();
    const provinces = await Province.find();
    const stats = await this.updateStatistics(schools, provinces);

    return {
      data: stats.data.majorDistribution,
      lastUpdated: stats.lastUpdated,
    };
  }

  // 获取就业趋势数据
  static async getEmploymentTrend() {
    const provinces = await Province.find(
      {},
      {
        name: 1,
        statistics: {
          $elemMatch: { name: "GDP" },
        },
      }
    );

    const nationalTrend =
      provinces[0]?.statistics[0]?.yearlyData.map((year) => ({
        year: year.year.toString(),
        value: (
          provinces.reduce((sum, province) => {
            const yearData = province.statistics[0]?.yearlyData.find(
              (y) => y.year === year.year
            );
            return sum + (yearData?.value || 0);
          }, 0) / provinces.length
        ).toFixed(2),
      })) || [];

    const provinceTrends = provinces.map((province) => ({
      name: province.name,
      data: province.statistics[0]?.yearlyData || [],
    }));

    return {
      nationalTrend,
      provinceTrends,
    };
  }

  // 获取收入水平比较数据
  static async getSalaryComparison() {
    const provinces = await Province.find(
      {},
      {
        name: 1,
        type: 1,
        statistics: {
          $elemMatch: { name: "income" },
        },
      }
    );

    const salaryData = provinces.map((province) => ({
      name: province.name,
      data: province.statistics[0]?.yearlyData || [],
    }));

    const years = [
      ...new Set(
        provinces.flatMap(
          (p) => p.statistics[0]?.yearlyData.map((y) => y.year) || []
        )
      ),
    ].sort();

    return {
      years,
      unit: "元/年",
      provinces: salaryData,
    };
  }

  // 获取统计数据概览
  static async getNumberStatistics() {
    const statistics = await Statistics.findOne({ type: "school" });

    if (statistics && statistics.data) {
      return {
        schoolCount: statistics.data.schoolCount,
        majorCount: statistics.data.majorCount,
        provinceCount: statistics.data.provinceCount,
        provinces: statistics.data.provinces,
        lastUpdated: statistics.lastUpdated,
      };
    }

    const schools = await School.find();
    const provinces = await Province.find();
    const stats = await this.updateStatistics(schools, provinces);

    return {
      schoolCount: stats.data.schoolCount,
      majorCount: stats.data.majorCount,
      provinceCount: stats.data.provinceCount,
      provinces: stats.data.provinces,
      lastUpdated: stats.lastUpdated,
    };
  }

  // 私有辅助方法
  static getLevel1Hierarchy(hierarchy, code) {
    const level1 = hierarchy.level1.find((l1) => l1.code === code);
    if (level1) {
      const children = hierarchy.relationships.level1ToLevel2[code] || [];
      return {
        ...level1,
        children: children.map((l2Code) =>
          hierarchy.level2.find((l2) => l2.code === l2Code)
        ),
      };
    }
    return null;
  }

  static getLevel2Hierarchy(hierarchy, code) {
    const level2 = hierarchy.level2.find((l2) => l2.code === code);
    if (level2) {
      const children = hierarchy.relationships.level2ToLevel3[code] || [];
      return {
        ...level2,
        parent: hierarchy.level1.find((l1) => l1.code === level2.parentCode),
        children: children.map((l3Code) =>
          hierarchy.level3.find((l3) => l3.code === l3Code)
        ),
      };
    }
    return null;
  }

  static getLevel3Hierarchy(hierarchy, code) {
    const level3 = hierarchy.level3.find((l3) => l3.code === code);
    if (level3) {
      const parents = hierarchy.relationships.level3ToParents[code];
      return {
        ...level3,
        parents: {
          level1: hierarchy.level1.find((l1) => l1.code === parents.level1),
          level2: hierarchy.level2.find((l2) => l2.code === parents.level2),
          type: hierarchy.types.find((t) => t.code === parents.type),
        },
      };
    }
    return null;
  }

  static async getMajorTree() {
    const statistics = await Statistics.findOne({ type: "school" });
    if (!statistics || !statistics.data.majorHierarchy) {
      throw new Error("未找到统计数据");
    }

    const hierarchy = statistics.data.majorHierarchy;

    // 构建树状结构
    const tree = hierarchy.level1.map((l1) => {
      // 获取一级学科的二级学科列表
      const l1Children =
        hierarchy.relationships.level1ToLevel2.get(l1.code) || [];

      return {
        key: l1.code,
        title: l1.name,
        value: l1.value,
        level: "level1",
        children: l1Children
          .map((l2Code) => {
            const l2 = hierarchy.level2.find((l2) => l2.code === l2Code);
            if (!l2) return null;

            // 获取二级学科的三级专业列表
            const l2Children =
              hierarchy.relationships.level2ToLevel3.get(l2.code) || [];

            return {
              key: l2.code,
              title: l2.name,
              value: l2.value,
              level: "level2",
              parentKey: l1.code,
              children: l2Children
                .map((l3Code) => {
                  const l3 = hierarchy.level3.find((l3) => l3.code === l3Code);
                  if (!l3) return null;

                  // 获取三级专业的父级关系
                  const parents = hierarchy.relationships.level3ToParents.get(
                    l3.code
                  );

                  return {
                    key: l3.code,
                    title: l3.name,
                    value: l3.value,
                    parentKey: l2.code,
                    level: "level3",
                    type: l3.type,
                    parents: parents
                      ? {
                          level1Code: parents.level1,
                          level2Code: parents.level2,
                          typeCode: parents.type,
                        }
                      : null,
                  };
                })
                .filter(Boolean), // 移除空值
            };
          })
          .filter(Boolean), // 移除空值
      };
    });

    // 计算每个层级的统计数据
    const summary = {
      level1Count: hierarchy.level1.length,
      level2Count: hierarchy.level2.length,
      level3Count: hierarchy.level3.length,
      typeCount: hierarchy.types.length,
      totalMajors: hierarchy.level3.reduce((sum, l3) => sum + l3.value, 0),
    };

    // 添加类型统计
    const typeStats = hierarchy.types.map((type) => ({
      key: type.code,
      title: type.name,
      value: type.value,
    }));

    return {
      tree,
      types: typeStats,
      lastUpdated: statistics.lastUpdated,
      summary,
      // 添加扁平化的数据，方便前端查询
      flatData: {
        level1: hierarchy.level1.map((l1) => ({
          key: l1.code,
          title: l1.name,
          value: l1.value,
        })),
        level2: hierarchy.level2.map((l2) => ({
          key: l2.code,
          title: l2.name,
          value: l2.value,
          parentKey: l2.parentCode,
        })),
        level3: hierarchy.level3.map((l3) => ({
          key: l3.code,
          title: l3.name,
          value: l3.value,
          parentKey: l3.parentCode,
          type: l3.type,
        })),
      },
    };
  }

  static async calculateStatistics(schools, provinces) {
    // 初始化统计数据
    const uniqueMajors = new Set();
    const typeCount = new Map();
    const level1Count = new Map();
    const level2Count = new Map();
    const level3Count = new Map();

    // 关系映射
    const level1ToLevel2 = new Map();
    const level2ToLevel3 = new Map();
    const level3ToParents = new Map();

    // 遍历所有学校和专业
    schools.forEach((school) => {
      school.children?.forEach((major) => {
        if (!major) return;

        // 生成唯一编码
        const level1Code = major.level2_code || "unknown";
        const level2Code = major.level3_code || "unknown";
        const level3Code = major.special_id || "unknown";
        const typeCode = major.special_type || "unknown";

        // 添加到唯一专业集合
        uniqueMajors.add(level3Code);

        // 统计专业类型
        if (major.type_name) {
          const typeData = typeCount.get(typeCode) || {
            name: major.type_name,
            code: typeCode,
            value: 0,
          };
          typeData.value++;
          typeCount.set(typeCode, typeData);
        }

        // 统计一级学科
        if (major.level2_name) {
          const level1Data = level1Count.get(level1Code) || {
            name: major.level2_name,
            code: level1Code,
            value: 0,
          };
          level1Data.value++;
          level1Count.set(level1Code, level1Data);

          // 建立一级到二级的关系
          if (!level1ToLevel2.has(level1Code)) {
            level1ToLevel2.set(level1Code, new Set());
          }
          if (level2Code !== "unknown") {
            level1ToLevel2.get(level1Code).add(level2Code);
          }
        }

        // 统计二级学科
        if (major.level3_name) {
          const level2Data = level2Count.get(level2Code) || {
            name: major.level3_name,
            code: level2Code,
            value: 0,
            parentCode: level1Code,
          };
          level2Data.value++;
          level2Count.set(level2Code, level2Data);

          // 建立二级到三级的关系
          if (!level2ToLevel3.has(level2Code)) {
            level2ToLevel3.set(level2Code, new Set());
          }
          if (level3Code !== "unknown") {
            level2ToLevel3.get(level2Code).add(level3Code);
          }
        }

        // 统计三级专业
        const level3Data = level3Count.get(level3Code) || {
          name: major.special_name,
          code: level3Code,
          value: 0,
          parentCode: level2Code,
          type: typeCode,
        };
        level3Data.value++;
        level3Count.set(level3Code, level3Data);

        // 建立三级专业的父级关系
        level3ToParents.set(level3Code, {
          level1: level1Code,
          level2: level2Code,
          type: typeCode,
        });
      });
    });

    // 转换 Set 为数组并构建最终的统计数据
    const statistics = {
      schoolCount: schools.length,
      majorCount: uniqueMajors.size,
      provinceCount: provinces.length,
      provinces: provinces.map((p) => p.name),
      uniqueMajors: Array.from(uniqueMajors),
      majorHierarchy: {
        types: Array.from(typeCount.values()),
        level1: Array.from(level1Count.values()),
        level2: Array.from(level2Count.values()),
        level3: Array.from(level3Count.values()),
        relationships: {
          level1ToLevel2: Object.fromEntries(
            Array.from(level1ToLevel2.entries()).map(([key, value]) => [
              key,
              Array.from(value),
            ])
          ),
          level2ToLevel3: Object.fromEntries(
            Array.from(level2ToLevel3.entries()).map(([key, value]) => [
              key,
              Array.from(value),
            ])
          ),
          level3ToParents: Object.fromEntries(level3ToParents),
        },
      },
    };

    // 计算专业分布
    statistics.majorDistribution = Array.from(level1Count.values()).map(
      ({ name, value }) => ({
        name,
        value,
      })
    );

    return statistics;
  }
}
